// Copyright (c) 2024 CHANGLEI. All rights reserved.

import 'package:charts_grasp/src/circular_chart/renderer/circular_series.dart';
import 'package:charts_grasp/src/circular_chart/renderer/renderer_base.dart';
import 'package:charts_grasp/src/circular_chart/renderer/renderer_extension.dart';
import 'package:charts_grasp/src/common/utils/typedef.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

class PieSeries<T, D> extends CircularSeries<T, D> {
  PieSeries({
    super.key,
    super.onCreateRenderer,
    super.onRendererCreated,
    super.onPointTap,
    super.onPointDoubleTap,
    super.onPointLongPress,
    super.dataSource,
    ChartValueMapper<T, D>? xValueMapper,
    ChartValueMapper<T, num>? yValueMapper,
    ChartValueMapper<T, Color>? pointColorMapper,
    ChartShaderMapper<T>? pointShaderMapper,
    ChartValueMapper<T, String>? pointRadiusMapper,
    ChartValueMapper<T, String>? dataLabelMapper,
    ChartValueMapper<T, String>? sortFieldValueMapper,
    super.startAngle,
    super.endAngle,
    super.radius,
    super.explode,
    super.explodeAll,
    super.explodeIndex,
    super.explodeGesture,
    super.explodeOffset,
    super.groupTo,
    super.groupMode,
    super.pointRenderMode,
    super.emptyPointSettings,
    Color? strokeColor,
    double? strokeWidth,
    super.opacity,
    super.dataLabelSettings,
    super.enableTooltip,
    super.name,
    super.animationDuration,
    super.animationDelay,
    super.selectionBehavior,
    super.sortingOrder,
    super.legendIconType,
    super.initialSelectedDataIndexes,
  }) : super(
            xValueMapper: (index) => xValueMapper!(dataSource![index], index),
            yValueMapper: (index) => yValueMapper!(dataSource![index], index),
            pointColorMapper: (index) =>
                pointColorMapper != null ? pointColorMapper(dataSource![index], index) : null,
            pointRadiusMapper:
                pointRadiusMapper == null ? null : (index) => pointRadiusMapper(dataSource![index], index),
            dataLabelMapper: (index) => dataLabelMapper != null ? dataLabelMapper(dataSource![index], index) : null,
            sortFieldValueMapper:
                sortFieldValueMapper != null ? (index) => sortFieldValueMapper(dataSource![index], index) : null,
            pointShaderMapper: pointShaderMapper != null
                ? (dynamic data, index, color, rect) =>
                    pointShaderMapper(dataSource![index], index, color, rect)
                : null,
            borderColor: strokeColor,
            borderWidth: strokeWidth,);

  PieSeriesRenderer? createRenderer(CircularSeries<T, D> series) {
    PieSeriesRenderer? seriesRenderer;
    if (onCreateRenderer != null) {
      seriesRenderer = onCreateRenderer!(series) as PieSeriesRenderer;
      return seriesRenderer;
    }
    return PieSeriesRendererExtension();
  }

  @override
  bool operator ==(Object other) {
    if (identical(this, other)) {
      return true;
    }
    if (other.runtimeType != runtimeType) {
      return false;
    }

    return other is PieSeries &&
        other.animationDuration == animationDuration &&
        other.animationDelay == animationDelay &&
        other.borderColor == borderColor &&
        other.borderWidth == borderWidth &&
        other.dataLabelMapper == dataLabelMapper &&
        other.dataLabelSettings == dataLabelSettings &&
        other.dataSource == dataSource &&
        other.emptyPointSettings == emptyPointSettings &&
        other.enableTooltip == enableTooltip &&
        other.endAngle == endAngle &&
        other.explode == explode &&
        other.explodeAll == explodeAll &&
        other.explodeGesture == explodeGesture &&
        other.explodeIndex == explodeIndex &&
        other.explodeOffset == explodeOffset &&
        other.groupMode == groupMode &&
        other.groupTo == groupTo &&
        listEquals(other.initialSelectedDataIndexes, initialSelectedDataIndexes) &&
        other.legendIconType == legendIconType &&
        other.name == name &&
        other.onCreateRenderer == onCreateRenderer &&
        other.onRendererCreated == onRendererCreated &&
        other.onPointTap == onPointTap &&
        other.onPointDoubleTap == onPointDoubleTap &&
        other.onPointLongPress == onPointLongPress &&
        other.opacity == opacity &&
        other.pointColorMapper == pointColorMapper &&
        other.pointRadiusMapper == pointRadiusMapper &&
        other.pointRenderMode == pointRenderMode &&
        other.pointShaderMapper == pointShaderMapper &&
        other.radius == radius &&
        other.selectionBehavior == selectionBehavior &&
        other.sortFieldValueMapper == sortFieldValueMapper &&
        other.sortingOrder == sortingOrder &&
        other.startAngle == startAngle &&
        other.xValueMapper == xValueMapper &&
        other.yValueMapper == yValueMapper;
  }

  @override
  int get hashCode {
    final List<Object?> values = <Object?>[
      animationDuration,
      animationDelay,
      borderColor,
      borderWidth,
      dataLabelMapper,
      dataLabelSettings,
      dataSource,
      emptyPointSettings,
      enableTooltip,
      endAngle,
      explode,
      explodeAll,
      explodeGesture,
      explodeIndex,
      explodeOffset,
      groupMode,
      groupTo,
      initialSelectedDataIndexes,
      legendIconType,
      name,
      onCreateRenderer,
      onRendererCreated,
      onPointTap,
      onPointDoubleTap,
      onPointLongPress,
      opacity,
      pointColorMapper,
      pointRadiusMapper,
      pointRenderMode,
      pointShaderMapper,
      radius,
      selectionBehavior,
      sortFieldValueMapper,
      sortingOrder,
      startAngle,
      xValueMapper,
      yValueMapper,
    ];
    return Object.hashAll(values);
  }
}
